using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Web.Mvc;

namespace DevelopmentKit.Extensions.MvcContrib
{
    public static class CheckBoxListExtensions
    {
        public static MvcHtmlString CheckBoxList(this HtmlHelper helper, string name, IEnumerable<SelectListItem> selectList)
        {
            return CheckBoxList(helper, name, selectList, new { });
        }

        public static object GetObjectPropertyValue(object t, string propertyname)
        {
            if (null != t)
            {
                var property = t.GetType().GetProperty(propertyname);
                if (property != null)
                {
                    object o = property.GetValue(t, null);
                    if (o != null)
                    {
                        return o;
                    }
                }
            } 
            return null;
        }

        public static MvcHtmlString CheckBoxList(this HtmlHelper helper, string name, IEnumerable<SelectListItem> selectList, object htmlAttributes)
        {
            var propertyValue = GetObjectPropertyValue(helper.ViewData.Model, name);
            var values = new List<string>();
            if (propertyValue != null && propertyValue is int[])
            {
                values = (propertyValue as int[]).Select(x => x.ToString(CultureInfo.InvariantCulture)).ToList();
            }
            var attributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);

            attributes.Add("type", "checkbox");
            attributes.Add("name", name); 

            var stringBuilder = new StringBuilder();
            if (attributes.ContainsKey("class"))
            {
                stringBuilder.AppendFormat("<div class=\"{0}\">", attributes["class"]);
            }
            else
            {
                stringBuilder.Append("<div>");
            }
            var i = 0;
            foreach (var selectItem in selectList)
            { 
                var id = string.Format("{0}_{1}", name, i++);
                IDictionary<string, object> newHtmlAttributes = attributes.DeepCopy();
                newHtmlAttributes.Add("id", id);
                newHtmlAttributes.Add("value", selectItem.Value);
                if (selectItem.Selected||values.Contains(selectItem.Value))
                {
                    newHtmlAttributes.Add("checked", "checked");
                }

                var tagBuilder = new TagBuilder("input");
                tagBuilder.MergeAttributes<string, object>(newHtmlAttributes);
                stringBuilder.Append(tagBuilder.ToString(TagRenderMode.SelfClosing));

                var labelTag = new TagBuilder("label");
                labelTag.InnerHtml = selectItem.Text;
                labelTag.Attributes.Add("for",id);
                stringBuilder.Append(labelTag.ToString(TagRenderMode.Normal)); 
            }

            stringBuilder.Append("</div>");
            return MvcHtmlString.Create(stringBuilder.ToString());

        }
        private static IDictionary<string, object> DeepCopy(this IDictionary<string, object> ht)
        {
            Dictionary<string, object> _ht = new Dictionary<string, object>();

            foreach (var p in ht)
            {
                _ht.Add(p.Key, p.Value);
            }
            return _ht;
        }

    }
}